/*
 * Copyright (c) 2011, Andrew Cole
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

package net.andycole.xmiparser.transfer;

import java.util.HashSet;
import java.util.ArrayList;

/**
 * Represents an Actionscript class or interface.
 * @author Andrew Cole
 */
public class TransferClass extends BaseType
{
   private String _className;
   private String _packagePath;
   private ArrayList<String> _implementsVector;
   private String   _extends;
   private String   _accessLevel;
   private ArrayList<TransferOperation> _methodsVector;
   private ArrayList<TransferAttribute> _attributeVector;
   private HashSet<String> _dependencyVector;
   private HashSet<String> _associationVector;
   private boolean _isInterface;
   private int _methodId;
   private int _fieldId;

   // will contain a list of extends, implements,
   // associations, realizes, methods and fields
   public TransferClass()
   {
      super();
      _className = "";
      _packagePath = "";
      _implementsVector = new ArrayList();
      _extends = "";
      _accessLevel = "public";
      _methodsVector = new ArrayList();
      _attributeVector = new ArrayList();
      _isInterface = false;
      _dependencyVector = new HashSet();
      _associationVector = new HashSet();
      _methodId = 0;
      _fieldId = 0;
   }

   public TransferOperation[] getMethods()
   {
      TransferOperation[] temp = new TransferOperation[_methodsVector.size()];
      return _methodsVector.toArray(temp);
   }

   public void addMethod(String accessLevel, String methodName,
                         TransferParameter[] params)
   {
      TransferOperation newMethod = new TransferOperation(methodName, accessLevel);
      newMethod.setId(getQualifiedClassName()+"."+
                      newMethod.getName()+
                      _methodId++);
      _methodsVector.add(newMethod);
   }
   
   public void addMethod(TransferOperation newMethod)
   {
      newMethod.setId(getQualifiedClassName()+"."+
                      newMethod.getName()+
                      _methodId++);
      _methodsVector.add(newMethod);
   }

   public TransferAttribute[] getAttributes()
   {
      TransferAttribute[] temp = new TransferAttribute[_attributeVector.size()];
      return _attributeVector.toArray(temp);
   }

   public String[] getDependencies()
   {
      String[] temp = new String[_dependencyVector.size()];
      return _dependencyVector.toArray(temp);
   }
   public void addDependency(String depend)
   {
      if (_dependencyVector.contains(depend) ||
          _implementsVector.contains(depend) ||
          depend.equals(_packagePath+"."+_className))
         return;
      _dependencyVector.add(depend);
   }

   public String[] getAssociations()
   {
      String[] temp = new String[_associationVector.size()];
      return _associationVector.toArray(temp);
   }
   public void addAssociation(String association)
   {
      if (_implementsVector.contains(association) ||
          association.equals(_packagePath+"."+_className))
         return;
      if (_dependencyVector.contains(association))
         _dependencyVector.remove(association);
      _associationVector.add(association);
   }

   public void addAttribute(String accessLevel, String field, String type)
   {
      TransferAttribute newField = new TransferAttribute(field, type, accessLevel,
                                                         false, false, false);
      _attributeVector.add(newField);
   }
   public void addAttribute(TransferAttribute newField)
   {
      _attributeVector.add(newField);
   }

   public void setIsInterface()
   {
      _isInterface = true;
   }
   public boolean isInterface()
   {
      return _isInterface;
   }

   public String getPackagePath()
   {
      return _packagePath;
   }
   public void setPackagePath(String pkgPath)
   {
      _packagePath = pkgPath;
   }

   public String getQualifiedClassName()
   {
      String fullClassName = "";
      if (_packagePath != null &&
          _packagePath.length() > 0)
         fullClassName = _packagePath + ".";
      fullClassName += _className;
      return fullClassName;
   }

   public String getAccessLevel()
   {
      return _accessLevel;
   }
   public void setAccessLevel(String access)
   {
      _accessLevel = access;
   }

   public String getClassName()
   {
      return _className;
   }
   public void setClassName(String newClassName)
   {
      _className = newClassName;
   }

   public void addImplement(String implementClass)
   {
      _implementsVector.add(implementClass);
   }
   public String[] getImplementsArray()
   {
      String[] temp = new String[_implementsVector.size()];
      return _implementsVector.toArray(temp);
   }

   public void setExtends(String extendsStr)
   {
      _extends = extendsStr;
   }
   public String getExtends()
   {
      return _extends;
   }

   @Override
   public int hashCode()
   {
      return _className.hashCode();
   }

   @Override
   public boolean equals(Object compareTo)
   {
      if (!(compareTo instanceof TransferClass))
         return false;
      if (compareTo == this)
         return true;
      final TransferClass compareClass = (TransferClass)compareTo;
      if (!_className.equals(compareClass.getClassName()))
         return false;

      return true;
   }

   @Override
   public String toString()
   {
      return getQualifiedClassName();
   }
}
